package com.echo.echovividlive.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.echo.echovividlive.common.UserThread;
import com.echo.echovividlive.domain.dto.LiveRoomPageDTO;
import com.echo.echovividlive.domain.dto.PageQueryDTO;
import com.echo.echovividlive.domain.entity.LiveRecord;
import com.echo.echovividlive.domain.entity.LiveRoom;
import com.echo.echovividlive.domain.entity.Result;
import com.echo.echovividlive.domain.vo.LiveInfoVO;
import com.echo.echovividlive.domain.vo.LiveVO;
import com.echo.echovividlive.domain.vo.PageVO;
import com.echo.echovividlive.mapper.LiveRecordMapper;
import com.echo.echovividlive.mapper.LiveRoomMapper;
import com.echo.echovividlive.service.ILiveRoomService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.echo.echovividlive.utils.TimeUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.stream.Collectors;

import static com.echo.echovividlive.common.Constants.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiajunjie
 * @since 2024-11-26
 */
@Service
@RequiredArgsConstructor
public class LiveRoomServiceImpl extends ServiceImpl<LiveRoomMapper, LiveRoom> implements ILiveRoomService {

    private final LiveRoomMapper liveRoomMapper;
    private final StringRedisTemplate stringRedisTemplate;
    private final FileStorageService fileStorageService;
    private final LiveRecordMapper liveRecordMapper;

    @Value("${living.server.address}")
    private String livingServerAddress;

    @Value("${living.server.m3u8}")
    private String livingServerM3u8;

    @Value("${dromara.x-file-storage.minio[2].bucket-name}")
    private String LIVE_BUKET;

    @Value("${dromara.x-file-storage.minio[2].platform}")
    private String LIVE_PLATFORM;

    @Value("${dromara.x-file-storage.minio[0].end-point}")
    private String MINIO_ADDRESS;

    @Override
    @Transactional
    public Result living(LiveRoom liveRoom) {
        if(StrUtil.isBlank(liveRoom.getPushStreamCode())){
            return Result.error("推流码为空");
        }
        Integer userId = UserThread.getUserId();
        liveRoom.setUserId(userId);
        liveRoom.setStatus(true);
        liveRoom.setCreateTime(TimeUtil.getCurrentTime());
        String url = livingServerAddress+liveRoom.getPushStreamCode()+livingServerM3u8;
        liveRoom.setUrl(url);
        this.save(liveRoom);
        return Result.success(liveRoom);
    }

    @Override
    public Result getCountByRoomId(Integer roomId) {
        String s = stringRedisTemplate.opsForValue().get(LIVE_USER_COUNTER + roomId);
        return Result.success(Integer.parseInt(s!=null?s:"0"));
    }

    @Override
    public Result pageList(LiveRoomPageDTO pageQueryDTO) {
        PageHelper.startPage(pageQueryDTO.getPageIndex(), pageQueryDTO.getPageSize()==null?10:pageQueryDTO.getPageSize());
        Page<LiveVO> pages =  liveRoomMapper.pageList(pageQueryDTO);
        pages.forEach(liveVO -> {
            String count = stringRedisTemplate.opsForValue().get(LIVE_USER_COUNTER + liveVO.getRoomId());
            liveVO.setOnlineCount(count==null?0:Integer.parseInt(count));
        });
        return Result.success(new PageVO(pages.getTotal(),pages.getResult()));
    }

    @Override
    public Result uploadCover(MultipartFile file) {
        FileInfo upload = fileStorageService.of(file)
                .setPlatform(LIVE_PLATFORM)
                //.setSaveFilename(userId+System.currentTimeMillis()+"_avatar.jpg")
                .upload();
        String cover = MINIO_ADDRESS+'/'+LIVE_BUKET+upload.getUrl();
        return Result.success(cover);
    }

    @Override
    public Result getRoomInfoById(Integer roomId) {
        LiveInfoVO res = liveRoomMapper.selectRoomInfoById(roomId);
        String s = stringRedisTemplate.opsForValue().get(LIVE_USER_COUNTER + roomId);
        res.setOnlineCount(Integer.parseInt(s!=null?s:"0"));
        return Result.success(res);
    }

    @Override
    @Transactional
    public void closeLiving(Integer roomId) {
        LiveRoom liveRoom = this.getById(roomId);
        LiveRecord liveRecord = new LiveRecord();
        BeanUtil.copyProperties(liveRoom, liveRecord);
        // 记录本次直播信息
        liveRecord.setEndTime(TimeUtil.getCurrentTime());
        List<String> range = stringRedisTemplate.opsForList().range(LIVE_GIFT_KEY + roomId, 0, -1);
        if(range==null || range.isEmpty()){
            liveRecord.setGiftTotalValue(0);
        } else {
            List<Integer> collect = range.stream().map(Integer::parseInt).collect(Collectors.toList());
            liveRecord.setGiftTotalValue(collect.stream().mapToInt(Integer::intValue).sum());
        }
        this.removeById(roomId);
        liveRecordMapper.insert(liveRecord);
        stringRedisTemplate.delete(LIVE_GIFT_KEY + roomId);
        stringRedisTemplate.delete(LIVE_ROOM_KEY + roomId);
        stringRedisTemplate.delete(LIVE_USER_COUNTER + roomId);
    }
}
